package cn.sell.filter;

import lombok.extern.log4j.Log4j2;
import org.springframework.core.annotation.Order;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @ClassName:AccessLogFilter
 * @Description: TODO: 日志过滤器
 * @Author: Limi
 * @Contact : qq(2393839633),Email(13924223985@163.com)
 * @Date: 2020/7/21 17:43
 * @Version: 1.0
 **/
@Log4j2
@Order(1)
@WebFilter(urlPatterns = "/app/rest/*")
public class AccessLogFilter implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest req = ((HttpServletRequest) request);
        HttpServletResponse res = ((HttpServletResponse) response);

        // 防止流读取一次后就没有了, 所以需要将流继续写出去
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        RequestBodyReaderWrapper requestBodyReaderWrapper = new RequestBodyReaderWrapper(httpServletRequest);
        String reqStr = HttpHelper.getReqStr(requestBodyReaderWrapper);

        // 防止流读取一次后就没有了, 所以需要将流继续写出去
        HttpServletResponse httpServletResponse = (HttpServletResponse) response;
        ResponseBodyReaderWrapper responseBodyReaderWrapper = new ResponseBodyReaderWrapper(httpServletResponse); // 包装响应对象 resp 并缓存响应数据

        //获取请求中的流，将取出来的字符串，再次转换成流，然后把它放入到新request对象中。
        // 在chain.doFiler方法中传递新的request对象
        if (requestBodyReaderWrapper == null) {
            filterChain.doFilter(request, response);
        } else {
            filterChain.doFilter(requestBodyReaderWrapper, responseBodyReaderWrapper);
        }
        String content = responseBodyReaderWrapper.getBody();
        String queryString = req.getQueryString();
        if (null == queryString) {
            log.info("\n请求路径：\n{}\n请求报文：\n{} \n", req.getRequestURL(), reqStr);
        } else {
            log.info("\n请求路径：\n{}\n请求体：\n{} \n", req.getRequestURL() + "?" + queryString, reqStr);
        }
        log.info("\n响应报文：\n{} \n", content);
    }
}
